<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>构造函数和析构函数</title>
<link media="all" rel="stylesheet" type="text/css" href="styles/03e73060321a0a848018724a6c83de7f-theme-base.css" />
<link media="all" rel="stylesheet" type="text/css" href="styles/03e73060321a0a848018724a6c83de7f-theme-medium.css" />

 </head>
 <body class="docs"><div class="navbar navbar-fixed-top">
  <div class="navbar-inner clearfix">
    <ul class="nav" style="width: 100%">
      <li style="float: left;"><a href="language.oop5.autoload.html">« 类的自动加载</a></li>
      <li style="float: right;"><a href="language.oop5.visibility.html">访问控制（可见性） »</a></li>
    </ul>
  </div>
</div>
<div id="breadcrumbs" class="clearfix">
  <ul class="breadcrumbs-container">
    <li><a href="index.html">PHP Manual</a></li>
    <li><a href="language.oop5.html">类与对象</a></li>
    <li>构造函数和析构函数</li>
  </ul>
</div>
<div id="layout">
  <div id="layout-content"><div id="language.oop5.decon" class="sect1">
 <h2 class="title">构造函数和析构函数</h2>

 <div class="sect2" id="language.oop5.decon.constructor">
  <h3 class="title">构造函数</h3>
   <div class="methodsynopsis dc-description" id="object.construct">
    <span class="methodname"><strong>__construct</strong></span>(<span class="methodparam"><span class="type"><a href="language.types.declarations.html#language.types.declarations.mixed" class="type mixed">mixed</a></span> <code class="parameter">...$values</code><span class="initializer"> = &quot;&quot;</span></span>): <span class="type"><span class="type void">void</span></span></div>

  <p class="para">
   PHP 允许开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法，所以非常适合在使用对象之前做一些初始化工作。
  </p>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <span class="simpara">
    如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数，需要在子类的构造函数中调用
    <span class="function"><strong>parent::__construct()</strong></span>。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承（假如没有被定义为
    private 的话）。
   </span>
  </p></blockquote>
  <div class="example" id="example-227">
   <p><strong>示例 #1 继承中的构造函数</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">BaseClass&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">__construct</span><span style="color: #007700">()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;</span><span style="color: #DD0000">"In&nbsp;BaseClass&nbsp;constructor\n"</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br />class&nbsp;</span><span style="color: #0000BB">SubClass&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">BaseClass&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">__construct</span><span style="color: #007700">()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">__construct</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;</span><span style="color: #DD0000">"In&nbsp;SubClass&nbsp;constructor\n"</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br />class&nbsp;</span><span style="color: #0000BB">OtherSubClass&nbsp;</span><span style="color: #007700">extends&nbsp;</span><span style="color: #0000BB">BaseClass&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;继承&nbsp;BaseClass&nbsp;的构造函数<br /></span><span style="color: #007700">}<br /><br /></span><span style="color: #FF8000">//&nbsp;In&nbsp;BaseClass&nbsp;constructor<br /></span><span style="color: #0000BB">$obj&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">BaseClass</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">//&nbsp;In&nbsp;BaseClass&nbsp;constructor<br />//&nbsp;In&nbsp;SubClass&nbsp;constructor<br /></span><span style="color: #0000BB">$obj&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">SubClass</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">//&nbsp;In&nbsp;BaseClass&nbsp;constructor<br /></span><span style="color: #0000BB">$obj&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">OtherSubClass</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</code></div>
   </div>

  </div>
  <p class="para">
   与其它方法不同， <a href="language.oop5.decon.html#object.construct" class="link">__construct()</a>
   在继承时不受<a href="language.oop5.basic.html#language.oop.lsp" class="link">签名兼容性规则</a>的约束。
  </p>
  <p class="para">
   自 PHP 5.3.3 起，在命名空间中，与类名同名的方法不再作为构造函数。不使用命名空间中的类则不受影响。
    构造函数是一个普通的方法，在对应对象实例化时自动被调用。
    因此可以定义任何数量的参数，可以是必选、可以有类型、可以有默认值。
    构造器的参数放在类名后的括号里调用。
  </p>
  <div class="example" id="example-228">
   <p><strong>示例 #2 使用构造器参数</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">Point&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;</span><span style="color: #0000BB">int&nbsp;$x</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;</span><span style="color: #0000BB">int&nbsp;$y</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;</span><span style="color: #0000BB">__construct</span><span style="color: #007700">(</span><span style="color: #0000BB">int&nbsp;$x</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">int&nbsp;$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">x&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$x</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$y</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #FF8000">//&nbsp;两个参数都传入<br /></span><span style="color: #0000BB">$p1&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Point</span><span style="color: #007700">(</span><span style="color: #0000BB">4</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">5</span><span style="color: #007700">);<br /></span><span style="color: #FF8000">//&nbsp;仅传入必填的参数。&nbsp;$y&nbsp;会默认取值&nbsp;0。<br /></span><span style="color: #0000BB">$p2&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Point</span><span style="color: #007700">(</span><span style="color: #0000BB">4</span><span style="color: #007700">);<br /></span><span style="color: #FF8000">//&nbsp;使用命名参数（PHP&nbsp;8.0&nbsp;起）:<br /></span><span style="color: #0000BB">$p3&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Point</span><span style="color: #007700">(</span><span style="color: #0000BB">y</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">5</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">x</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">4</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</code></div>
    </div>

  </div>
   <p class="para">
   如果一个类没有构造函数，以及构造函数的参数不是必填项时，括号就可以省略。
   </p>
   <div class="sect3">
    <h4 class="title">旧式风格的构造器</h4>
    <p class="para">
     PHP 8.0.0 之前，全局命名空间内的类如果有一个同名的方法，则会解析为旧式风格的构造器。
     虽然函数能被当作构造器，但该语法已被废弃，并会导致 <strong><code>E_DEPRECATED</code></strong> 错误。
     如果 <a href="language.oop5.decon.html#object.construct" class="link">__construct()</a> 和同名方法同时存在时，
     会调用 <a href="language.oop5.decon.html#object.construct" class="link">__construct()</a>。
    </p>
    <p class="para">
     以下两种情况时，与类同名的方法不再有特殊意义：命名空间中的类、PHP 8.0.0 起的任何类。
    </p>
    <p class="para">新代码中要使用 <a href="language.oop5.decon.html#object.construct" class="link">__construct()</a>。
    </p>
   </div>
   <div class="sect3" id="language.oop5.decon.constructor.promotion">
    <h4 class="title">构造器属性提升</h4>
    <p class="para">
     PHP 8.0.0 起，构造器的参数也可以相应提升为类的属性。
     构造器的参数赋值给类属性的行为很普遍，否则无法操作。
     而构造器提升的功能则为这种场景提供了便利。
     因此上面的例子可以用以下方式重写：
    </p>
    <div class="example" id="example-229">
     <p><strong>示例 #3 使用构造器属性提升</strong></p>
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">Point&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;</span><span style="color: #0000BB">__construct</span><span style="color: #007700">(protected&nbsp;</span><span style="color: #0000BB">int&nbsp;$x</span><span style="color: #007700">,&nbsp;protected&nbsp;</span><span style="color: #0000BB">int&nbsp;$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span>
</span>
</code></div>
     </div>

    </div>
    <p class="para">
     当构造器参数带访问控制（visibility modifier）时，PHP 会同时把它当作对象属性和构造器参数，
     并赋值到属性。
     构造器可以是空的，或者包含其他语句。
     参数值赋值到相应属性后执行正文中额外的代码语句。
    </p>
    <p class="para">
     并非所有参数都需要提升。可以混合提升或不提升参数作为属性，也不需要按顺序。
     提升后的参数不影响构造器内代码调用。
    </p>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <p class="para">
     对象属性的类型不能为 <span class="type"><a href="language.types.callable.html" class="type callable">callable</a></span> 以避免为引擎带来混淆。
     因此提升的参数也不能是 <span class="type"><a href="language.types.callable.html" class="type callable">callable</a></span>。
     其他任意 <a href="language.types.declarations.html" class="link">类型声明</a> 是允许的。
     </p>
    </p></blockquote>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <p class="para">
      放在构造器提升参数里的<a href="language.attributes.html" class="link">属性</a>会同时复制为属性和参数。
     </p>
    </p></blockquote>
   </div>

   <div class="sect3" id="language.oop5.decon.constructor.new">
    <h4 class="title">初始化新功能</h4>
    <p class="para">
     自 PHP 8.1.0 起，对象可以用于默认参数值，静态变量，全局常量，以及属性参数。<span class="function"><a href="function.define.html" class="function">define()</a></span>
     现在也接受对象。
    </p>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <p class="para">
      禁止使用动态类名、非字符串类名以及匿名类。禁止使用参数解包。禁止使用不支持的表达式作为参数。
     </p>
    </p></blockquote>
    <div class="example" id="example-230">
     <p><strong>示例 #4 初始化中使用 new</strong></p>
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #FF8000">//&nbsp;全部允许：<br /></span><span style="color: #007700">static&nbsp;</span><span style="color: #0000BB">$x&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Foo</span><span style="color: #007700">;<br /><br />const&nbsp;</span><span style="color: #0000BB">C&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Foo</span><span style="color: #007700">;<br />&nbsp;<br />function&nbsp;</span><span style="color: #0000BB">test</span><span style="color: #007700">(</span><span style="color: #0000BB">$param&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Foo</span><span style="color: #007700">)&nbsp;{}<br />&nbsp;<br /></span><span style="color: #FF8000">#[AnAttribute(new&nbsp;Foo)]<br /></span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">Test&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;</span><span style="color: #0000BB">__construct</span><span style="color: #007700">(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">$prop&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Foo</span><span style="color: #007700">,<br />&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;{}<br />}<br /><br /></span><span style="color: #FF8000">//&nbsp;全部禁止（编译时错误）:<br /></span><span style="color: #007700">function&nbsp;</span><span style="color: #0000BB">test</span><span style="color: #007700">(<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$a&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;(</span><span style="color: #0000BB">CLASS_NAME_CONSTANT</span><span style="color: #007700">)(),&nbsp;</span><span style="color: #FF8000">//&nbsp;动态类名<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$b&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;class&nbsp;{},&nbsp;</span><span style="color: #FF8000">//&nbsp;匿名类<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$c&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">A</span><span style="color: #007700">(...[]),&nbsp;</span><span style="color: #FF8000">//&nbsp;参数解包<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$d&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">B</span><span style="color: #007700">(</span><span style="color: #0000BB">$abc</span><span style="color: #007700">),&nbsp;</span><span style="color: #FF8000">//&nbsp;不支持的常量表达式<br /></span><span style="color: #007700">)&nbsp;{}<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</code></div>
     </div>

    </div>
   </div>
   
   <div class="sect3" id="language.oop5.decon.constructor.static">
    <h4 class="title">Static 创造方法</h4>
    <p class="para">
     在 PHP 中每个 class 只能有一个构造器。
     然而有些情况下，需要用不同的输入实现不同的方式构造对象。
     这种情况下推荐使用 static 方法包装构造。
    </p>
    <div class="example" id="example-231">
     <p><strong>示例 #5 使用 static 创造方法</strong></p>
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">Product&nbsp;</span><span style="color: #007700">{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;?</span><span style="color: #0000BB">int&nbsp;$id</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;?</span><span style="color: #0000BB">string&nbsp;$name</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;function&nbsp;</span><span style="color: #0000BB">__construct</span><span style="color: #007700">(?</span><span style="color: #0000BB">int&nbsp;$id&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">,&nbsp;?</span><span style="color: #0000BB">string&nbsp;$name&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">id&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$id</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$name</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;function&nbsp;</span><span style="color: #0000BB">fromBasicData</span><span style="color: #007700">(</span><span style="color: #0000BB">int&nbsp;$id</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">string&nbsp;$name</span><span style="color: #007700">):&nbsp;static&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$new&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;static(</span><span style="color: #0000BB">$id</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #0000BB">$new</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;function&nbsp;</span><span style="color: #0000BB">fromJson</span><span style="color: #007700">(</span><span style="color: #0000BB">string&nbsp;$json</span><span style="color: #007700">):&nbsp;static&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$data&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">json_decode</span><span style="color: #007700">(</span><span style="color: #0000BB">$json</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;static(</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'id'</span><span style="color: #007700">],&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'name'</span><span style="color: #007700">]);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;function&nbsp;</span><span style="color: #0000BB">fromXml</span><span style="color: #007700">(</span><span style="color: #0000BB">string&nbsp;$xml</span><span style="color: #007700">):&nbsp;static&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;自定义代码逻辑。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$data&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">convert_xml_to_array</span><span style="color: #007700">(</span><span style="color: #0000BB">$xml</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$new&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;static();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$new</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">id&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'id'</span><span style="color: #007700">];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$new</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'name'</span><span style="color: #007700">];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #0000BB">$new</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #0000BB">$p1&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">Product</span><span style="color: #007700">::</span><span style="color: #0000BB">fromBasicData</span><span style="color: #007700">(</span><span style="color: #0000BB">5</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'Widget'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$p2&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">Product</span><span style="color: #007700">::</span><span style="color: #0000BB">fromJson</span><span style="color: #007700">(</span><span style="color: #0000BB">$some_json_string</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$p3&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">Product</span><span style="color: #007700">::</span><span style="color: #0000BB">fromXml</span><span style="color: #007700">(</span><span style="color: #0000BB">$some_xml_string</span><span style="color: #007700">);</span>
</span>
</code></div>
     </div>

    </div>
    <p class="para">
     可以设置构造器为 private 或 protected，防止自行额外调用。
     这时只有 static 方法可以实例化一个类。
     由于它们位于同一个定义的 class 因此可以访问私有方法，也不需要在同一个对象实例中。
     当然构造器不一定要设置为 private，是否合理取决于实际情况。
    </p>
    <p class="para">
     三个 static 方法展示了对象以不同方式的实例化方式。
    </p>
    <ul class="simplelist">
     <li class="member"><code class="code">fromBasicData()</code> 把所需的全部参数传入构造器，创建对象并返回结果。</li>
     <li class="member"><code class="code">fromJson()</code> 接受 JSON 字符串，，预处理成构造器所需的格式，然后返回新的对象。</li>
     <li class="member"><code class="code">fromXml()</code> 接受 XML 字符串并解析，然后创建一个单纯的对象。
     由于参数都是可选的，使得可以忽略所有参数去调用构造器。然后为对象的属性赋值后返回结果。</li>
    </ul>
    <p class="para">
    在以上三个例子中，<code class="code">static</code> 关键词会被翻译成代码所在类的类名。
     这个例子中是 <code class="code">Product</code>。
    </p>
   </div>
 </div>

 <div class="sect2" id="language.oop5.decon.destructor">
  <h3 class="title">析构函数</h3>
   <div class="methodsynopsis dc-description" id="object.destruct">
    <span class="methodname"><strong>__destruct</strong></span>(): <span class="type"><span class="type void">void</span></span></div>

  <p class="para">
   PHP 有析构函数的概念，这类似于其它面向对象的语言，如
   C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
  </p>
  <div class="example" id="example-232">
   <p><strong>示例 #6 析构函数示例</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">MyDestructableClass&nbsp;<br /></span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">__construct</span><span style="color: #007700">()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;</span><span style="color: #DD0000">"In&nbsp;constructor\n"</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">__destruct</span><span style="color: #007700">()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;</span><span style="color: #DD0000">"Destroying&nbsp;"&nbsp;</span><span style="color: #007700">.&nbsp;</span><span style="color: #0000BB">__CLASS__&nbsp;</span><span style="color: #007700">.&nbsp;</span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #0000BB">$obj&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">MyDestructableClass</span><span style="color: #007700">();</span>
</span>
</code></div>
    </div>

  </div>
  <p class="para">
   和构造函数一样，父类的析构函数不会被引擎暗中调用。要执行父类的析构函数，必须在子类的析构函数体中显式调用
   <span class="function"><strong>parent::__destruct()</strong></span>。此外也和构造函数一样，子类如果自己没有定义析构函数则会继承父类的。
  </p>
  <p class="para">
   析构函数即使在使用 <span class="function"><a href="function.exit.html" class="function">exit()</a></span>
   终止脚本运行时也会被调用。在析构函数中调用
   <span class="function"><a href="function.exit.html" class="function">exit()</a></span> 将会中止其余关闭操作的运行。
  </p>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <p class="para">
    析构函数在脚本关闭时调用，此时所有的 HTTP
    头信息已经发出。脚本关闭时的工作目录有可能和在 SAPI（如 apache）中时不同。
   </p>
  </p></blockquote>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <p class="para">
    试图在析构函数（在脚本终止时被调用）中抛出一个异常会导致致命错误。
   </p>
  </p></blockquote>
 </div>

</div></div></div></body></html>